package com.huilan.base.esl.service.acd.domain.model.queue;


import com.huilan.base.esl.service.acd.domain.model.ACDException;
import com.huilan.base.esl.service.acd.domain.model.agent.Agent;
import com.huilan.base.esl.service.acd.domain.model.phoneinline.PhoneInline;
import lombok.Getter;
import lombok.Setter;
import org.redisson.api.RLiveObjectService;
import org.redisson.api.annotation.REntity;
import org.redisson.api.annotation.RId;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.huilan.base.esl.service.acd.domain.model.Base.getRedisson;

@Getter
@Setter
@REntity
public class Queue{

    @RId
    private String id;
    private Set<Agent> agents;
    private Set<PhoneInline> phoneInlines;
    private QueueACDEnum queueACDEnum;

    public Queue() {
    }

    private Queue(String id, QueueACDEnum queueACDEnum) {
        this.id = id;
        this.queueACDEnum = queueACDEnum;
    }

    public static Queue create(String id, QueueACDEnum queueACDEnum){
        Queue queue = get(id);
        if (queue != null){
            return queue;
        }
        RLiveObjectService liveObjectService = getRedisson().getLiveObjectService();
        queue = liveObjectService.persist(new Queue(id, queueACDEnum));
        return queue;
    }
    public static Queue get(String id){
        RLiveObjectService liveObjectService = getRedisson().getLiveObjectService();
        return liveObjectService.get(Queue.class, id);
    }

    public Agent chooseAgent() {
        Set<Agent> agents = getAgents();
        if ( agents == null || agents.size() == 0)
            throw new ACDException("技能组里一个坐席也没有");

        List<Agent> list = agents.stream().filter(s -> s.idle()).collect(Collectors.toList());
        if (list == null || list.size() == 0)
            throw new ACDException("没有空闲坐席");

        // 根据 acd 策略选择坐席
        Agent agent = getQueueACDEnum().getIacd().choose(list);

        // 选好坐席之后 锁定坐席开始工作
        if (agent.startWork()){
            return agent;
        }else{
            // 锁定失败 重新选择
            return chooseAgent();
        }
    }

    // 用户开始排队
    public void addPhoneInline(PhoneInline phoneInline) {
        getPhoneInlines().add(phoneInline);
    }
    public void delPhoneInline(PhoneInline phoneInline) {
        getPhoneInlines().remove(phoneInline);
    }

    public void addAgent(Agent agent){
        getAgents().add(agent);
    }
    public void delAgent(Agent agent){
        getAgents().remove(agent);
    }


}
